package com.christina.engine.processing.impl;

import com.christina.engine.processing.AbstractRequestProcessor;
import com.christina.engine.processing.model.ProcessingContext;
import com.christina.engine.processing.model.ProcessingResult;
import com.christina.service.application.model.UnifiedRequest;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 验证处理器
 * 负责验证请求的基本格式和必要字段
 */
@Component
public class ValidationProcessor extends AbstractRequestProcessor {
    
    private static final String PROCESSOR_NAME = "ValidationProcessor";
    private static final int PROCESSOR_ORDER = 100; // 第一个执行的处理器
    
    // 验证规则配置
    private static final int MIN_USER_INPUT_LENGTH = 1;
    private static final int MAX_USER_INPUT_LENGTH = 10000;
    private static final Pattern SESSION_ID_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]{8,64}$");
    
    public ValidationProcessor() {
        super(PROCESSOR_NAME, PROCESSOR_ORDER);
    }
    
    @Override
    protected ProcessingResult doProcess(ProcessingContext context) {
        logger.debug("Starting request validation for requestId: {}", context.getRequestId());
        
        List<String> validationErrors = new ArrayList<>();
        
        // 验证基本请求信息
        validateBasicRequest(context, validationErrors);
        
        // 验证用户ID
        validateUserId(context, validationErrors);
        
        // 验证会话ID
        validateSessionId(context, validationErrors);
        
        // 验证用户输入
        validateUserInput(context, validationErrors);
        
        // 验证请求类型
        validateRequestType(context, validationErrors);
        
        // 验证客户端信息
        validateClientInfo(context, validationErrors);
        
        // 如果有验证错误，返回失败结果
        if (!validationErrors.isEmpty()) {
            String errorMessage = "Request validation failed: " + String.join("; ", validationErrors);
            logger.warn("Validation failed for requestId {}: {}", context.getRequestId(), errorMessage);
            
            // 记录验证失败的详细信息
            context.setProcessingData("validationErrors", validationErrors);
            context.setProcessingData("validationStatus", "FAILED");
            
            return ProcessingResult.failure(errorMessage, null, PROCESSOR_NAME);
        }
        
        // 验证成功，记录验证状态
        context.setProcessingData("validationStatus", "PASSED");
        context.setProcessingData("validationTimestamp", System.currentTimeMillis());
        
        logger.debug("Request validation passed for requestId: {}", context.getRequestId());
        
        return ProcessingResult.builder()
                .success(true)
                .shouldContinue(true)
                .processorName(PROCESSOR_NAME)
                .resultData("validationStatus", "PASSED")
                .resultData("validatedFields", getValidatedFields())
                .build();
    }
    
    /**
     * 验证基本请求信息
     */
    private void validateBasicRequest(ProcessingContext context, List<String> errors) {
        if (context.getOriginalRequest() == null) {
            errors.add("Original request cannot be null");
            return;
        }
        
        UnifiedRequest request = context.getOriginalRequest();
        
        // 验证请求时间
        if (request.getRequestTime() == null) {
            errors.add("Request time cannot be null");
        }
    }
    
    /**
     * 验证用户ID
     */
    private void validateUserId(ProcessingContext context, List<String> errors) {
        Long userId = context.getUserId();
        
        if (userId == null) {
            errors.add("User ID cannot be null");
            return;
        }
        
        if (userId <= 0) {
            errors.add("User ID must be positive");
        }
        
        // 检查用户ID是否在合理范围内
        if (userId > Long.MAX_VALUE / 2) {
            errors.add("User ID is too large");
        }
    }
    
    /**
     * 验证会话ID
     */
    private void validateSessionId(ProcessingContext context, List<String> errors) {
        String sessionId = context.getSessionId();
        
        if (sessionId == null || sessionId.trim().isEmpty()) {
            errors.add("Session ID cannot be null or empty");
            return;
        }
        
        // 验证会话ID格式
        if (!SESSION_ID_PATTERN.matcher(sessionId).matches()) {
            errors.add("Session ID format is invalid (must be 8-64 characters, alphanumeric, underscore, or hyphen)");
        }
    }
    
    /**
     * 验证用户输入
     */
    private void validateUserInput(ProcessingContext context, List<String> errors) {
        UnifiedRequest request = context.getOriginalRequest();
        String userInput = request.getUserInput();
        
        if (userInput == null || userInput.trim().isEmpty()) {
            errors.add("User input cannot be null or empty");
            return;
        }
        
        // 验证输入长度
        if (userInput.length() < MIN_USER_INPUT_LENGTH) {
            errors.add("User input is too short (minimum " + MIN_USER_INPUT_LENGTH + " characters)");
        }
        
        if (userInput.length() > MAX_USER_INPUT_LENGTH) {
            errors.add("User input is too long (maximum " + MAX_USER_INPUT_LENGTH + " characters)");
        }
        
        // 验证输入内容不全是空白字符
        if (userInput.trim().isEmpty()) {
            errors.add("User input cannot contain only whitespace characters");
        }
        
        // 检查是否包含恶意内容（基础检查）
        if (containsSuspiciousContent(userInput)) {
            errors.add("User input contains potentially malicious content");
        }
    }
    
    /**
     * 验证请求类型
     */
    private void validateRequestType(ProcessingContext context, List<String> errors) {
        UnifiedRequest request = context.getOriginalRequest();
        UnifiedRequest.RequestType requestType = request.getRequestType();
        
        if (requestType == null) {
            errors.add("Request type cannot be null");
            return;
        }
        
        // 根据请求类型进行特定验证
        switch (requestType) {
            case TEXT:
                validateTextRequest(request, errors);
                break;
            case VOICE:
                validateVoiceRequest(request, errors);
                break;
            case IMAGE:
                validateImageRequest(request, errors);
                break;
            case MULTIMODAL:
                validateMultimodalRequest(request, errors);
                break;
            default:
                errors.add("Unsupported request type: " + requestType);
        }
    }
    
    /**
     * 验证客户端信息
     */
    private void validateClientInfo(ProcessingContext context, List<String> errors) {
        UnifiedRequest request = context.getOriginalRequest();
        UnifiedRequest.ClientInfo clientInfo = request.getClientInfo();
        
        if (clientInfo == null) {
            // 客户端信息是可选的，但如果提供了就需要验证
            return;
        }
        
        // 验证平台信息
        if (clientInfo.getPlatform() != null && !isValidPlatform(clientInfo.getPlatform())) {
            errors.add("Invalid platform: " + clientInfo.getPlatform());
        }
        
        // 验证设备类型
        if (clientInfo.getDeviceType() != null && !isValidDeviceType(clientInfo.getDeviceType())) {
            errors.add("Invalid device type: " + clientInfo.getDeviceType());
        }
        
        // 验证IP地址格式
        if (clientInfo.getIpAddress() != null && !isValidIpAddress(clientInfo.getIpAddress())) {
            errors.add("Invalid IP address format: " + clientInfo.getIpAddress());
        }
    }
    
    /**
     * 验证文本请求
     */
    private void validateTextRequest(UnifiedRequest request, List<String> errors) {
        // 文本请求的特定验证逻辑
        String userInput = request.getUserInput();
        
        // 检查文本编码
        if (!isValidTextEncoding(userInput)) {
            errors.add("Text contains invalid characters or encoding");
        }
    }
    
    /**
     * 验证语音请求
     */
    private void validateVoiceRequest(UnifiedRequest request, List<String> errors) {
        // 语音请求的特定验证逻辑
        // 这里可以添加语音数据格式验证
        if (request.getExtraParameters() == null || 
            !request.getExtraParameters().containsKey("audioData")) {
            errors.add("Voice request must contain audio data");
        }
    }
    
    /**
     * 验证图像请求
     */
    private void validateImageRequest(UnifiedRequest request, List<String> errors) {
        // 图像请求的特定验证逻辑
        if (request.getExtraParameters() == null || 
            !request.getExtraParameters().containsKey("imageData")) {
            errors.add("Image request must contain image data");
        }
    }
    
    /**
     * 验证多模态请求
     */
    private void validateMultimodalRequest(UnifiedRequest request, List<String> errors) {
        // 多模态请求的特定验证逻辑
        if (request.getExtraParameters() == null || request.getExtraParameters().isEmpty()) {
            errors.add("Multimodal request must contain additional data");
        }
    }
    
    /**
     * 检查是否包含可疑内容
     */
    private boolean containsSuspiciousContent(String input) {
        // 基础的恶意内容检查
        String lowerInput = input.toLowerCase();
        
        // 检查SQL注入模式
        String[] sqlPatterns = {"drop table", "delete from", "insert into", "update set", 
                               "union select", "script>", "<script", "javascript:", "eval("};
        
        for (String pattern : sqlPatterns) {
            if (lowerInput.contains(pattern)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 验证平台信息
     */
    private boolean isValidPlatform(String platform) {
        return platform.matches("^(web|mobile|desktop|api)$");
    }
    
    /**
     * 验证设备类型
     */
    private boolean isValidDeviceType(String deviceType) {
        return deviceType.matches("^(phone|tablet|computer|unknown)$");
    }
    
    /**
     * 验证IP地址格式
     */
    private boolean isValidIpAddress(String ipAddress) {
        // 简单的IP地址格式验证（IPv4）
        String ipv4Pattern = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$";
        return ipAddress.matches(ipv4Pattern) || ipAddress.equals("localhost") || ipAddress.equals("127.0.0.1");
    }
    
    /**
     * 验证文本编码
     */
    private boolean isValidTextEncoding(String text) {
        // 检查文本是否包含有效的UTF-8字符
        try {
            byte[] bytes = text.getBytes("UTF-8");
            String decoded = new String(bytes, "UTF-8");
            return decoded.equals(text);
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 获取已验证的字段列表
     */
    private List<String> getValidatedFields() {
        return List.of("userId", "sessionId", "userInput", "requestType", "requestTime", "clientInfo");
    }
    
    @Override
    protected void preProcess(ProcessingContext context) {
        super.preProcess(context);
        context.updateState("VALIDATING");
    }
    
    @Override
    protected void postProcess(ProcessingContext context, ProcessingResult result) {
        super.postProcess(context, result);
        if (result.isSuccess()) {
            context.updateState("VALIDATED");
        } else {
            context.updateState("VALIDATION_FAILED");
        }
    }
    
    @Override
    public boolean supports(ProcessingContext context) {
        // 验证处理器支持所有类型的请求
        return context != null && context.getOriginalRequest() != null;
    }
}